/**
 * 软件著作权：中国金币总公司
 *
 * 系统名称：  中金国衡业务管理信息系统
 *
 * 文件名称：  PubParamService.java
 *
 * 功能描述：  公共参数服务
 * 
 * 版本历史：
 * 
 * 2014-06-07   1.0.0版 （龙色波）（创建文件）
 */
package com.dfhc.pub.service;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;

import org.quickbundle.project.RmGlobalReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import com.dfhc.ISystemConstant;
import com.dfhc.PjException;
import com.dfhc.util.ConvertHelper;
import com.dfhc.util.DateUtil;
import com.dfhc.util.FileOperateHelper;
import com.dfhc.util.MD5Util;
import com.dfhc.util.StringHelper;



/**
 * 公共参数服务
 * 
 * @author 龙色波
 * @see 参见的类
 * @remark 默认将类中的所有public函数纳入事务管理
 */
@Service
//默认将类中的所有public函数纳入事务管理
@Transactional(readOnly = true)
public class PubParamService {
	
	private static final Pattern TEL_PATTERN = Pattern.compile("^((13[0-9])|(147)|(17[0,6-9])|(15[^4,\\D])|(18[0-9]))\\d{8}$");
	@Autowired
	private SmbFileService smbFileService;
	
	
	/**
	 * 获取根目录
	 * @return
	 */
	public String getRootPath(){
		String value = RmGlobalReference.get(ISystemConstant.DICTIONARY_PATH, ISystemConstant.DICTIONARY_ROOT_PATH);
		if(StringHelper.isEmpty(value)){
			throw new PjException("根目录参数尚未配置!");
		}else{
			//不是以路径分隔符结束，则连接分隔符
			if(!value.trim().endsWith(File.separator)){
				return value.trim()+File.separator;
			}else{
				return value.trim();
			}
		}
		
	}
	
	/**
		 * 支付密码md5加密(用户ID+明文密码+附加串，MD5加密)
		 * @param id
		 * @param password
		 * @return
		 */
		public String md5PaymentPassword(String id,String password){
			try {
				return MD5Util.md5Encode(id+password);
			} catch (NoSuchAlgorithmException e) {
				e.printStackTrace();
				throw new PjException(e);
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
				throw new PjException(e);
			}
		}
		
		/**
		 * 验证手机号码（暂缺固定电话的验证）
		 */
		public boolean checkTelephone(String telephone){
			Pattern p = TEL_PATTERN;
			Matcher matcher = p.matcher(telephone);
			if (!matcher.matches()) {
				return false;
			}
			return true;
		}

		/**
		 * 验证码短信
		 * 
		 * @return
		 */
		public String getTemplateYSMessage() {
			String value = RmGlobalReference.get(ISystemConstant.TEMPLET, ISystemConstant.TEMPLET_MESSAGE_YS);
			if (StringHelper.isEmpty(value)) {
				throw new PjException("短信模板参数尚未配置!");
			} else {
				return value.trim();
			}
		}
		/**
		 * 打印登录验证码md5加密(用户id+8位随机码)
		 * @param userId
		 * @param code
		 * @return
		 */
		public String md5PrintLoginVirectyCode(String userId,String code){
			try{
				return MD5Util.md5Encode(userId+code);
			} catch (NoSuchAlgorithmException e) {
				e.printStackTrace();
				throw new PjException(e);
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
				throw new PjException(e);
			}
		}
		
		/**
		 * 获取rm.xml配置的webAppName.root.home目录
		 * @return
		 */
		public String getConfigRootPath(){
			return System.getProperty(ISystemConstant.WEBAPPNAME_ROOT_HOME);
		}	
		
		
	    
	    /**
	     * 二次加密用户的密码
	     * @param vo：该vo 的密码只在页面进行了一次加密
	     * @return
	     */
	    public  org.quickbundle.orgauth.rmuser.vo.RmUserVo   signRmUserPwd(org.quickbundle.orgauth.rmuser.vo.RmUserVo vo){
	    	
	    	String uuid=UUID.randomUUID().toString();//获取一个随机数，作为加密的key
	    	
	    	String oldPwd=vo.getPassword();//未加密的用户vo的密码
	    	String  newPwd="";
	    	try{
	    	  newPwd=MD5Util.md5Encode(oldPwd, uuid);//加密后的密码
	    	} catch (NoSuchAlgorithmException e) {
				e.printStackTrace();
				throw new PjException(e);
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
				throw new PjException(e);
			}
	    	vo.setAttribute2(uuid);//存放随机数
	    	vo.setPassword(newPwd);//设置新密密码
	    	
	    	
	    	return vo;
	    	
	    }
	    
	    /**
	     * 用户加密
	     * @param uuid
	     * @param oldPwd
	     * @return
	     */
	    public String signRmUserPwd(String uuid,String oldPwd){
	    	
	    	uuid=uuid==null?"":uuid;
	    	if(StringHelper.isEmpty(oldPwd)){
	    		
	    		throw new PjException("用户输入密码为空");
	    	}
	    	String  newPwd;
	    	
	    	try {
				newPwd=MD5Util.md5Encode(oldPwd, uuid);
			} catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
				e.printStackTrace();
				throw new PjException(e);
			}//加密后的密码
	    	
	    	return newPwd;
	    	
	    }
	    
	    
	    
	    /**
	     * 验证用户输入的登录密码
	     * 
	     * @param vo：从数据库中查出的用户vo
	     * @param pwd:用户页面输入的密码
	     * @return true=密码正确
	     */
	    
	    public  boolean  VailRmUserPwd(org.quickbundle.orgauth.rmuser.vo.RmUserVo vo ,String pwd){
	    	
	    	String uuid=vo.getAttribute2();//获取存放的随机数
	    	uuid=uuid==null?"":uuid;
	    	
	    	String rmPwd=vo.getPassword();//获取用户密码
	    	
	    	String newPwd;
			try {
				newPwd = MD5Util.md5Encode(pwd, uuid);
			} catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				throw new PjException(e);
			}//加密后的密码
	    	
	    	if(rmPwd.equals(newPwd)){
	    		
	    		return true;
	    		
	    	}else{
	    	
	    		return false;
	    	}
	    	
	    	
	    }
	    
		/**
		 * 获取文件加锁目录
		 * @return
		 */
		public String getFileLockPath(){
			String value = getRootPath();
			return value +ISystemConstant.FILE_LOCK_RELA_PATH+File.separator;
		}	
		
		 /**
	     * 根据任务类型查询数据：审核check、任务节点task、知会任务节点notify：获取表单属性
	     * @param taskType
	     * @return
	     */
	    public String getFormProp(String taskType){
	    	
	    	String value = RmGlobalReference.get(ISystemConstant.TASK_TYPE, taskType);
	    	
	    	if(StringHelper.isEmpty(value)){
	    		
	    		throw new PjException("根据任务类型没找到对应的表单属性");
	    	}
	    	
	    	value=value.trim();
	    	return value;
	    	
	    }
	    
	    /**
		 * 上传文件
		 * 
		 * @param file
		 * @throws IOException
		 * @throws IllegalStateException
		 */
		public String upload(MultipartFile file, String id, HttpServletRequest request)throws IllegalStateException, IOException {
			Date date = new Date();
			String nowDate = DateUtil.getDateStr(date, "yyyyMMdd");
			String originalFilename = file.getOriginalFilename();
			String path = nowDate + File.separator + File.separator + id + File.separator + File.separator;
			// 修改后的文件名称
			String fileName = DateUtil.getDateStr(date, "yyyyMMddHHmmss") + originalFilename.substring(originalFilename.lastIndexOf("."));

			String fullPath = getRootPath() + path;

			
			if(!isShareHost()){
				InputStream  ins = file.getInputStream();
				smbFileService.writeSubFile(ins,fileName, fullPath);
				ins.close();
			}else{
				if (!FileOperateHelper.isExists(fullPath)) {
					try {
						FileOperateHelper.newFolder(fullPath);
					} catch (Exception e) {
						if (!FileOperateHelper.isExists(fullPath)) {
							throw new PjException(e.getMessage());
						}
					}
				}
				File targetFile = new File(fullPath+fileName);
				file.transferTo(targetFile);
			}
			
			//如果本机不是共享主机，则复制文件存储到共享主机
			
			return path + fileName;
		}
		
		/**
		 * 查看本机是否为共享主机--如果为共享主机，则直接访问文件夹，不走读取共享文件夹的过程
		 * @return
		 * @author kang
		 */
		public boolean isShareHost(){
			List<String> ips = getLocalIpList();
			if(ips == null || ips.size() == 0){
				return true;
			}
			@SuppressWarnings("unchecked")
			Map<String, Object> map = RmGlobalReference.get(ISystemConstant.SMB_MESSAGE);
			if(map == null){
				return true;
			}
			String address=null;
			for(Map.Entry<String, Object> entry : map.entrySet()){
				if("地址".equals(entry.getValue())){
					address = entry.getKey();
				}
			}
			if(StringHelper.isEmpty(address)){
				return true;
			}
			return ips.contains(address);
		}
		/**
		 * 获取本机的所有内网IP
		 * @return
		 * @author kang
		 */
		@SuppressWarnings("rawtypes")
		public List<String> getLocalIpList(){
			List<String> list = new ArrayList<String>();
			Enumeration allNetInterfaces;
			try {
				allNetInterfaces = NetworkInterface.getNetworkInterfaces();
			
				InetAddress ip = null;
				while (allNetInterfaces.hasMoreElements())
				{
					NetworkInterface netInterface = (NetworkInterface) allNetInterfaces.nextElement();
					Enumeration addresses = netInterface.getInetAddresses();
					while (addresses.hasMoreElements()){
						ip = (InetAddress) addresses.nextElement();
						if (ip != null && ip instanceof Inet4Address){
							list.add(ip.getHostAddress());
						} 
					}
				}
			}catch (SocketException e) {
				e.printStackTrace();
			}
			return list;
		}
		/**
		 * 获取用户登录密码错误最大重试次数
		 * @return
		 * @throws Exception 
		 */
		public int getLoginFailRetryTimes() throws Exception {
			String value=RmGlobalReference.get(ISystemConstant.LOGIN_CONFIG, ISystemConstant.DICTIONARY_USER_PASSWORD_MAX_RETRY_TIMES);
			if(StringHelper.isEmpty(value)){
				throw new PjException("获取用户登录密码错误最大重试次数参数尚未配置!");
			}
			return ConvertHelper.toInt(value);
		}
		/**
		 * 用户登录密码错误达到最大次数被锁定的时间，以分钟为单位
		 * @return 
		 * @throws Exception 
		 */
		public int getUserLockTime() throws Exception {
			String value=RmGlobalReference.get(ISystemConstant.LOGIN_CONFIG, ISystemConstant.DICTIONARY_USER_LOGIN_LOCK_TIME);
			if(StringHelper.isEmpty(value)){
				throw new PjException("用户登录密码错误达到最大次数被锁定的时间(单位：分钟)参数尚未配置!");
			}
			return ConvertHelper.toInt(value);
		}
		/**
		 * 获取调试csrf开关
		 * @return
		 * @throws Exception
		 */
		public boolean isDebugCsrf() {
			String value = RmGlobalReference.get(ISystemConstant.DICTIONARY_DEBUG, ISystemConstant.DICTIONARY_DEBUG_CSRF);
			if (StringHelper.isEmpty(value)) {
				return false;
			}
			if(ISystemConstant.DICTIONARY_RM_YES_NOT_1.equals(value.trim())){
				return true;
			}else{
				return false;
			}
		}
		/**
		 * 获取调试解密url开关
		 * @return
		 * @throws Exception
		 */
		public boolean isDebugDecryptUrl() {
			String value = RmGlobalReference.get(ISystemConstant.DICTIONARY_DEBUG, ISystemConstant.DICTIONARY_DEBUG_DECRYPT_URL);
			if (StringHelper.isEmpty(value)) {
				return false;
			}
			if(ISystemConstant.DICTIONARY_RM_YES_NOT_1.equals(value.trim())){
				return true;
			}else{
				return false;
			}
		}			
		
}
